/**
 * @author ens12ilt - ens12ple
 */

package model.neuralnetwork;

import java.util.ArrayList;

import config.Config;

public class Neuron {
	
	private int _numberOfInputs;
	private ArrayList<Double> _weight;
	private ArrayList<Double> _inputs;
	private double _lastOutput;
	
	
	/**
	 * 
	 * @param n number of inputs
	 */
	public Neuron(int n){
		_numberOfInputs = n;
		_weight = new ArrayList<Double>();
		
		/* Initializing weight with random values */
		for(int i = 0; i < _numberOfInputs; i++){
			_weight.add(Math.random() - 0.5);
		}
	}
	
	public double getLastOutput() {
		return _lastOutput;
	}
	
	public double getWeight(int neuron) {
		return _weight.get(neuron);
	}
	
	public void setInputs(ArrayList<Double> inputs){
		_inputs = new ArrayList<Double>(inputs);
	}
	
	public double calculateWeightedSum() throws IllegalArgumentException{
		double sum = 0;
		if(_inputs.size() != _weight.size()){
			throw new IllegalArgumentException("Inputs size must match weight size !");
		}
		for(int i = 0; i < _inputs.size(); i++){
			sum += _weight.get(i) * _inputs.get(i);
		}
		return sum;
	}
	
	public double calculateWeightedSum(double error) throws IllegalArgumentException{
		double sum = 0;
		for(int i = 0; i < _weight.size(); i++){
			sum += _weight.get(i) * error;
		}
		return sum;
	}
	
	private double sigmoid(double weightedSum){
		return 1/(1 + Math.exp(-Config.LEARNING_RATE * weightedSum));
	}
	
	/**
	 * 
	 * @param weightedSum the input value for sigmoid
	 * @return the computed value for sigmoid
	 */
	public double activationFunction(double weightedSum){
		_lastOutput = sigmoid(weightedSum);
		return _lastOutput;
	}
	
	/**
	 * 
	 * @param errorOutput error found for this neuron
	 */
	public void updateWeight(double errorOutput){
		double newWeight;
		for(int i = 0; i < _weight.size(); i++){
			newWeight = _weight.get(i) + Config.LEARNING_RATE*errorOutput*_inputs.get(i);
			_weight.set(i, newWeight);
		}
	}	
}
